ATOM Documentation

← Back to App

Creative Tools Integration Documentation

Overview

Integration with Canva, Figma, and Adobe Creative Cloud for design creation, photo editing capabilities, and writing assistant tools.

**Features:**

  • Design tool OAuth integration (Canva, Figma, Adobe)
  • Photo editing with Sharp (crop, resize, filters, adjustments)
  • Writing assistants (Evernote, Grammarly stub)
  • Creative asset management UI
  • AI-powered design suggestions

Supported Providers

Design Tools

  • **Canva**: Design creation and template customization
  • **Figma**: Design collaboration and prototyping
  • **Adobe CC**: Photoshop and Illustrator editing

Photo Editing

  • **Sharp-based processing**: Crop, resize, filters, adjustments
  • **Real-time preview**: Client-side editing with API debouncing

Writing Tools

  • **Evernote**: Note management (OAuth 1.0a with signature generation)
  • **Grammarly**: Writing assistant (enterprise-only stub with LanguageTool alternative)

OAuth Setup

Canva

**Environment Variables:**

CANVA_CLIENT_ID=your_client_id
CANVA_CLIENT_SECRET=your_client_secret
CANVA_REDIRECT_URI=https://your-domain.com/api/integrations/canva/callback

**Dashboard Configuration:**

  1. Visit https://www.canva.com/developers/api
  2. Create a new OAuth application
  3. Configure redirect URI
  4. Enable scopes: design:read, design:write, design:export, template:read

**Usage:**

import { CanvaClient } from '@/lib/integrations/creative/canva-client';

const client = new CanvaClient(tenantId);
const authUrl = CanvaClient.getAuthorizationUrl(tenantId, state);
const designs = await client.listDesigns({ limit: 10 });

Figma

**Environment Variables:**

FIGMA_CLIENT_ID=your_client_id
FIGMA_CLIENT_SECRET=your_client_secret
FIGMA_REDIRECT_URI=https://your-domain.com/api/integrations/figma/callback

**Dashboard Configuration:**

  1. Visit https://www.figma.com/developers/api
  2. Create a new OAuth app
  3. Configure redirect URI
  4. Enable scopes: file:read, file:write, comments:write, team_library:read

**Usage:**

import { FigmaClient } from '@/lib/integrations/creative/figma-client';

const client = new FigmaClient(tenantId);
const file = await client.getFile(fileKey);

Adobe Creative Cloud

**Environment Variables:**

ADOBE_CLIENT_ID=your_client_id
ADOBE_CLIENT_SECRET=your_client_secret
ADOBE_REDIRECT_URI=https://your-domain.com/api/integrations/adobe/callback

**Dashboard Configuration:**

  1. Visit https://developer.adobe.com/creative-cloud/
  2. Create a new project
  3. Add APIs: Photoshop, Illustrator
  4. Configure IMS (Identity Management System)

**Multi-Service Support:**

import { AdobeClient } from '@/lib/integrations/creative/adobe-client';

const client = new AdobeClient(tenantId);
await client.psEditImage(imageId, { adjustments: { brightness: 20 } });
await client.aiCreateGraphic({ width: 1920, height: 1080 });

Photo Editing API

Upload Photo

POST /api/media/photos/upload
Content-Type: multipart/form-data

curl -X POST http://localhost:3000/api/media/photos/upload \
  -F "image=@photo.jpg" \
  -H "Cookie: session=..."

**Response:**

{
  "success": true,
  "data": {
    "id": "photo-123",
    "filename": "photo.jpg",
    "size": 1024000,
    "width": 1920,
    "height": 1080,
    "format": "jpg",
    "url": "/api/media/photos/photo-123"
  }
}

Edit Photo

POST /api/media/photos/:id/edit
Content-Type: application/json

{
  "crop": { "x": 10, "y": 10, "width": 500, "height": 500 },
  "adjustments": { "brightness": 20, "contrast": 10 },
  "filters": [{ "type": "grayscale" }]
}

Available Filters

FilterDescriptionParameters
grayscaleBlack and white conversionNone
sepiaWarm vintage toneNone
blurSoft focusintensity (1-10)
sharpenEdge enhancementNone
vintageCombined sepia + fadeNone
dramaticHigh contrast + saturationNone

Filter Presets

GET /api/media/filters?action=presets

**Response:**

{
  "success": true,
  "data": {
    "filters": [
      {
        "id": "grayscale",
        "name": "Grayscale",
        "description": "Basic black and white conversion"
      },
      {
        "id": "vintage",
        "name": "Vintage",
        "description": "Combined sepia + fade"
      }
    ]
  }
}

AI Suggestions

Design Suggestions

POST /api/creative/suggestions?type=design

{
  "prompt": "modern logo for tech startup",
  "context": {
    "brandColors": ["#FF0000", "#0000FF"],
    "industry": "technology",
    "targetAudience": "millennials"
  }
}

**Response:**

{
  "success": true,
  "data": {
    "suggestions": [
      {
        "layout": "minimalist with bold typography",
        "colors": ["#2C3E50", "#E74C3C", "#ECF0F1"],
        "fonts": ["Montserrat", "Open Sans"],
        "composition": "center-aligned with negative space"
      }
    ]
  }
}

Color Suggestions

GET /api/creative/suggestions?type=colors&brandKitId=xxx

**Response:**

{
  "success": true,
  "data": {
    "schemes": [
      {
        "name": "Complementary",
        "colors": ["#FF0000", "#00FF00", "#0000FF"],
        "accessibility": "AA"
      }
    ]
  }
}

API Reference

Canva Endpoints

  • GET /api/integrations/canva?action=connect - Start OAuth flow
  • GET /api/integrations/canva/callback - OAuth callback
  • DELETE /api/integrations/canva - Disconnect integration
  • POST /api/integrations/canva/designs - Create design
  • GET /api/integrations/canva/designs - List designs
  • GET /api/integrations/canva/templates - List templates

Figma Endpoints

  • GET /api/integrations/figma?action=connect - Start OAuth flow
  • GET /api/integrations/figma/callback - OAuth callback
  • DELETE /api/integrations/figma - Disconnect integration
  • GET /api/integrations/figma/files/:key - Get file
  • POST /api/integrations/figma/files - Create file

Adobe Endpoints

  • GET /api/integrations/adobe?action=connect&service=photoshop - Start OAuth
  • GET /api/integrations/adobe/callback - OAuth callback
  • DELETE /api/integrations/adobe?service=photoshop - Disconnect
  • POST /api/integrations/adobe/photoshop/edit - Edit image
  • POST /api/integrations/adobe/illustrator/create - Create graphic

Creative Assets

  • POST /api/creative/assets - Create asset from provider
  • GET /api/creative/assets - List with filters
  • PUT /api/creative/assets?id={id} - Update asset
  • DELETE /api/creative/assets?id={id} - Delete asset
  • POST /api/creative/assets/:id/export/{provider} - Cross-tool export

Cross-Tool Export

Export assets between providers:

POST /api/creative/assets/{id}/export/canva
POST /api/creative/assets/{id}/export/figma
POST /api/creative/assets/{id}/export/adobe

Agent Integration

Agents can use creative tools via skill invocations:

// Agent creates Canva design
import { CanvaClient } from '@/lib/integrations/creative/canva-client';

const canvaClient = new CanvaClient(tenantId);
const design = await canvaClient.createDesign({
  title: 'Marketing Graphic',
  type: 'social-media',
  templateId: 'template-123'
});

// Agent edits photo with Sharp
import { PhotoEditorService } from '@/lib/photo-editor';

const photoService = new PhotoEditorService();
const edited = await photoService.editPhoto(imageBuffer, {
  filters: [{ type: 'dramatic' }],
  adjustments: { brightness: 15, contrast: 10 }
});

// Agent gets AI suggestions
import { CreativeSuggestionsService } from '@/lib/ai/creative-suggestions';

const suggestionService = new CreativeSuggestionsService();
const suggestions = await suggestionService.suggestDesign(
  'modern logo',
  { industry: 'tech' }
);

Governance Actions

The following governance actions are required for creative tool operations:

  • CREATIVE_TOOLS_CANVA - Canva design operations
  • CREATIVE_TOOLS_FIGMA - Figma file operations
  • CREATIVE_TOOLS_ADOBE - Adobe editing operations
  • CREATIVE_TOOLS_PHOTO_EDIT - Photo editing
  • CREATIVE_TOOLS_EVERNOTE - Evernote note operations

Troubleshooting

OAuth Flow Fails

  • **Symptom**: Redirect to /integrations?error=canva_access_denied
  • **Cause**: Redirect URI mismatch or invalid state
  • **Fix**: Verify redirect URI matches exactly in provider dashboard
  • **Debug**: Check oauth_states table for state records

Sharp Installation Fails

  • **Symptom**: Error: libvips not found
  • **Cause**: Missing system dependency
  • **Fix**:
  • Ubuntu: sudo apt-get install libvips
  • MacOS: brew install vips
  • Alternative: Use pure-JS Jimp (slower)

Evernote OAuth 1.0a Fails

  • **Symptom**: Invalid signature error
  • **Cause**: Incorrect signature generation
  • **Fix**: Verify consumer key/secret, check timestamp is current
  • **Note**: Evernote uses legacy OAuth 1.0a (complex signature-based auth)

Grammarly Enterprise Only

  • **Symptom**: ENTERPRISE_ONLY error
  • **Cause**: Grammarly API requires enterprise contract
  • **Alternative**: Use LanguageTool (https://languagetool.org)
  • Open source
  • Free tier available
  • Self-hostable option
  • 20+ languages supported

Rate Limiting

All providers have rate limits:

ProviderLimitRetry-After
Canva100 req/min60s
Figma120 req/min60s
AdobeVaries300s

**Implementation**: Exponential backoff on 429 responses

if (response.status === 429) {
  const retryAfter = parseInt(response.headers.get('retry-after') || '60');
  await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
  // Retry request
}

Cross-Tool Export Fails

  • **Symptom**: Export fails with provider incompatibility
  • **Cause**: Provider-specific field mappings
  • **Fix**: Manual field mapping required
  • **Example**: Figma frames → Canva designs (different object models)

Examples

Create and Export Design

// 1. Create design from template
const client = new CanvaClient(tenantId);
const design = await client.createDesign({
  title: 'Summer Sale',
  templateId: 'template-456'
});

// 2. Export to PNG
const exportResult = await client.exportDesign(design.id, {
  type: 'png',
  quality: 'high'
});

// 3. Download from export URL
const response = await fetch(exportResult.exportUrl);
const buffer = await response.arrayBuffer();

Apply Photo Filters

import { PhotoEditorService } from '@/lib/photo-editor';

const photoService = new PhotoEditorService();

// Single filter
const grayscale = await photoService.applyGrayscale(imageBuffer);

// Multiple edits
const edited = await photoService.editPhoto(imageBuffer, {
  crop: { x: 0, y: 0, width: 1920, height: 1080 },
  filters: [
    { type: 'vintage' },
    { type: 'sharpen' }
  ],
  adjustments: {
    brightness: 10,
    contrast: 15,
    saturation: -5
  }
});

// Export to WebP
const webp = await photoService.export(edited, 'webp', 85);

AI-Powered Design Suggestions

import { CreativeSuggestionsService } from '@/lib/ai/creative-suggestions';

const service = new CreativeSuggestionsService();

// Get design suggestions
const suggestions = await service.suggestDesign(
  'modern minimalist logo',
  {
    brandColors: ['#FF5733', '#33FF57'],
    industry: 'technology',
    targetAudience: 'startups'
  }
);

// Get color schemes
const colors = await service.suggestColors({
  primary: '#FF5733'
});

// Get font recommendations
const fonts = await service.suggestFonts('presentation');

// Get layout suggestions
const layout = await service.suggestLayout('landing-page');

Testing

Test Coverage Goals

  • Creative clients: >80% (Canva, Figma, Adobe)
  • Photo editor service: >80%
  • Creative UI components: >75%

Run Tests

# Creative integration tests
npm test -- tests/integrations/creative/

# Photo editor tests
npm test -- tests/photo-editor.test.ts

# Creative component tests
npm test -- tests/components/creative.test.tsx

# API integration tests
npm test -- tests/api/creative.test.ts

Coverage Report

# Generate coverage report
npm run test:coverage

# View HTML report
open coverage/index.html

See Also